package com.frejoys.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.frejoys.common.dto.common.IdDto;
import com.frejoys.common.dto.store.ChangeSortDto;
import com.frejoys.common.dto.store.StoreCategorySaveDto;
import com.frejoys.common.dto.store.StoreCategoryUpdateDto;
import com.frejoys.common.enums.EShelves;
import com.frejoys.common.enums.EStatus;
import com.frejoys.common.error.HttpStatus;
import com.frejoys.common.exception.GeneralException;
import com.frejoys.common.vo.app.CategoryListVo;
import com.frejoys.common.vo.app.StoreCategoryListVo;
import com.frejoys.common.vo.store.StoreCategoryVo;
import com.frejoys.dao.entity.AgentStore;
import com.frejoys.dao.entity.Goods;
import com.frejoys.dao.entity.StoreCategory;
import com.frejoys.dao.mapper.AgentStoreMapper;
import com.frejoys.dao.mapper.GoodsMapper;
import com.frejoys.dao.mapper.StoreCategoryMapper;
import com.frejoys.service.StoreCategoryService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;

/**
 * @author wangzhicheng
 * @version 1.0
 * @date 2024/5/21 10:20
 */
@Service
@RequiredArgsConstructor
public class StoreCategoryServiceImpl extends ServiceImpl<StoreCategoryMapper, StoreCategory> implements StoreCategoryService {

    private final GoodsMapper goodsMapper;

    private final AgentStoreMapper agentStoreMapper;

    private final StoreCategoryMapper storeCategoryMapper;

    /**
     * 根据店铺id获取店铺类目
     *
     * @param storeId
     */
    @Override
    public List<StoreCategoryVo> listStoreCategory(Integer storeId) {
        LambdaQueryWrapper<StoreCategory> wrapper = Wrappers.lambdaQuery();
        wrapper.select(StoreCategory::getId, StoreCategory::getName, StoreCategory::getStatus).eq(StoreCategory::getStoreId, storeId)
                .gt(StoreCategory::getStatus, EStatus.del.getValue()).orderByAsc(StoreCategory::getSort);
        List<StoreCategory> storeCategories = baseMapper.selectList(wrapper);
        if (CollectionUtil.isEmpty(storeCategories)) {
            return Collections.emptyList();
        }
        return BeanUtil.copyToList(storeCategories, StoreCategoryVo.class);
    }

    /**
     * 根据店铺id获取店铺正常类目
     *
     * @param storeId
     */
    @Override
    public List<StoreCategoryVo> list(Integer storeId) {
        LambdaQueryWrapper<StoreCategory> wrapper = Wrappers.lambdaQuery();
        wrapper.select(StoreCategory::getId, StoreCategory::getName, StoreCategory::getStatus).eq(StoreCategory::getStoreId, storeId)
                .eq(StoreCategory::getStatus, EStatus.on.getValue()).orderByAsc(StoreCategory::getSort);
        List<StoreCategory> storeCategories = baseMapper.selectList(wrapper);
        if (CollectionUtil.isEmpty(storeCategories)) {
            return Collections.emptyList();
        }
        return BeanUtil.copyToList(storeCategories, StoreCategoryVo.class);
    }

    /**
     * 新增店铺类目
     *
     * @param dto
     */
    @Override
    public boolean addInfo(StoreCategorySaveDto dto) {
        validated(dto.getName(), dto.getStoreId(), null);
        StoreCategory storeCategory = BeanUtil.copyProperties(dto, StoreCategory.class);
        return save(storeCategory);
    }

    /**
     * 修改店铺类目
     *
     * @param dto
     */
    @Override
    public boolean upInfo(StoreCategoryUpdateDto dto) {
        validated(dto.getName(), dto.getStoreId(), dto.getId());
        LambdaUpdateWrapper<StoreCategory> wrapper = Wrappers.lambdaUpdate();
        if (dto.getSort() != null) {
            wrapper.set(StoreCategory::getSort, dto.getSort());
        }
        wrapper.set(StoreCategory::getName, dto.getName())
                .eq(StoreCategory::getId, dto.getId());
        return update(wrapper);
    }

    /**
     * 删除分类
     *
     * @param dto
     */
    @Override
    public boolean delInfo(IdDto dto,Long userId) {
        LambdaQueryWrapper<AgentStore> storeWrapper = new LambdaQueryWrapper<>();
        storeWrapper.select(AgentStore::getStoreId).eq(AgentStore::getUserId,userId);
        List<AgentStore> agentStores = agentStoreMapper.selectList(storeWrapper);
        if (agentStores.isEmpty()){
            throw new GeneralException(HttpStatus.storeNotFound);
        }

        List<Integer> storeIds = agentStores.stream().map(AgentStore::getStoreId).toList();

        LambdaQueryWrapper<StoreCategory> storeCategoryWrapper = new LambdaQueryWrapper<>();
        storeCategoryWrapper.select(StoreCategory::getId).in(StoreCategory::getStoreId,storeIds).eq(StoreCategory::getStatus,EStatus.on.getValue());
        List<StoreCategory> storeCategories = storeCategoryMapper.selectList(storeCategoryWrapper);
        List<Integer> ids = storeCategories.stream().map(StoreCategory::getId).toList();

        if (!ids.contains(dto.getId())){
            throw new GeneralException(HttpStatus.notStoreCategoryError);
        }

        LambdaQueryWrapper<Goods> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(Goods::getStoreCategoryId, dto.getId());
        if (goodsMapper.exists(wrapper)) {
            throw new GeneralException(HttpStatus.categoryHasGoods);
        }

        return update(Wrappers.<StoreCategory>lambdaUpdate().set(StoreCategory::getStatus, EStatus.del.getValue()).eq(StoreCategory::getId, dto.getId()));
    }

    /**
     * 修改品类顺序
     *
     * @param dtos
     */
    @Override
    public boolean changeSort(List<ChangeSortDto> dtos) {
        if (!dtos.isEmpty()) {
            for (int i = 0; i < dtos.size(); i++) {
                update(Wrappers.<StoreCategory>lambdaUpdate().set(StoreCategory::getSort, i).eq(StoreCategory::getId, dtos.get(i).getId()));
            }
        }
        return true;
    }

    @Override
    public List<StoreCategoryListVo> storeIdCategory(Integer storeId) {
        LambdaQueryWrapper<StoreCategory> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(StoreCategory::getId,StoreCategory::getName)
                .eq(StoreCategory::getStoreId,storeId)
                .eq(StoreCategory::getStatus,EStatus.on.getValue())
                .orderByAsc(StoreCategory::getSort);
        List<StoreCategory> list = baseMapper.selectList(wrapper);
        return BeanUtil.copyToList(list,StoreCategoryListVo.class);
    }


    private void validated(String name, Integer storeId, Integer id) {
        LambdaQueryWrapper<StoreCategory> wrapper = Wrappers.lambdaQuery();
        wrapper.select(StoreCategory::getId, StoreCategory::getName).eq(StoreCategory::getName, name).eq(StoreCategory::getStoreId, storeId)
                .gt(StoreCategory::getStatus, EStatus.del.getValue());
        if (id != null) {
            wrapper.ne(StoreCategory::getId, id);
        }
        if (ObjectUtil.isNotEmpty(getOnly(wrapper))) {
            throw new GeneralException(HttpStatus.sameNameIsExit);
        }
    }
}
